package com.ht.api.util;

import java.util.function.Supplier;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.context.ConfigurableApplicationContext;

import com.ht.api.HtWebApiMain;
import com.ht.api.db.Db;
import com.ht.api.db.Entity;
import com.ht.api.db.annotate.FuncParams;
import com.ht.api.db.bean.AjaxResult;
import com.ht.api.db.bean.DataResult;
import com.ht.api.db.bean.SessionBean;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.request.HandleRequestHelper;
import com.ht.api.db.request.HandleRequestUtil;
import com.ht.api.db.request.IHandleRequest;
import com.ht.api.db.util.FunctionUtil;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

/**
 * Call工具类
 * @author asq
 * @createTime 2025年4月15日 15:19:54
 */
public class CallTestUtil {
	/** 测试经常用的租户ID：花田 */
	private static final long TENANT = 1876286380045373440L;

	/**
	 * 测试一个Func
	 * @param key 接口key
	 * @return
	 */
	public static JSONObject autoTest(String key) {
		return autoTest(TENANT, key);
	}
	
	/**
	 * 测试一个Func
	 * @param tenantId 租户ID
	 * @param key 接口key
	 * @return
	 */
	public static JSONObject autoTest(long tenantId, String key) {
		return runWithSpring(() -> {
			DataResult result = HandleRequestUtil.callFunc(SessionBean.createByTenant(tenantId), key);
            System.out.println("测试结果: " + JSONUtil.toJsonPrettyStr(result));

            AjaxResult ajaxResult = null;
        	if (StrUtil.isBlank(result.getMsg())) {
        		ajaxResult = AjaxResult.success(result.getData());
        	} else {
        		ajaxResult = AjaxResult.success(result.getMsg(), result.getData());
        	}
        	
        	JSONObject json = JSONUtil.createObj();
        	json.putAll(ajaxResult);
        	return json;
        });
	}
	
	/**
	 * 测试一个Func
	 * @param key 接口key
	 * @param param 参数
	 * @return
	 */
	public static JSONObject autoTest(String key, JSONObject param) {
		return autoTest(TENANT, key, param);
	}
	
	/**
	 * 测试一个Func
	 * @param tenantId 租户ID
	 * @param key 接口key
	 * @param param 参数
	 * @return
	 */
	public static JSONObject autoTest(long tenantId, String key, JSONObject param) {
		return runWithSpring(() -> {
			DataResult result = HandleRequestUtil.callFunc(SessionBean.createByTenant(tenantId), key, param);
            System.out.println("测试结果: " + JSONUtil.toJsonPrettyStr(result));

            AjaxResult ajaxResult = null;
        	if (StrUtil.isBlank(result.getMsg())) {
        		ajaxResult = AjaxResult.success(result.getData());
        	} else {
        		ajaxResult = AjaxResult.success(result.getMsg(), result.getData());
        	}
        	
        	JSONObject json = JSONUtil.createObj();
        	json.putAll(ajaxResult);
        	return json;
        });
	}
	
	/**
	 * 获取专用接口的参数
	 * @param key
	 * @return
	 */
	public static JSONObject getFuncParam(String key) {
        return runWithSpring(() -> {
			IHandleRequest function = FunctionUtil.getFunction(key);
			if (function == null) {
				throw new HtException("找不到HandleRequest函数：" + key);
			}
			
			// 获取接口的参数配置
			FuncParams funcParams = function.getClass().getAnnotation(FuncParams.class);
			return HandleRequestHelper.getFuncParam(funcParams);
        });
	}
	
	/**
	 * 为接口创建result响应结果数据
	 * @param key 接口key
	 * @param result 响应结果数据
	 */
	public static void createResult(String key, JSONObject result) {
        runWithSpring(() -> {
            Entity call = Db.createSqlParser("call").where("key", key).findOne();
            if (call != null) {
            	call.set("result", result);
            	Db.insert(call);
            } else {
            	throw new HtException("接口不存在，key：" + key);
            }
        });
	}
	
	/**
	 * 保存一个接口类到call表
	 * @param implClass
	 */
	public static void saveFunc(Class<?> implClass) {
        runWithSpring(() -> {
    		Db.insert(HandleRequestHelper.saveOrUpdateCall(null, implClass));
        });
	}
	
	/**
	 * 启动spring环境，并执行业务代码
	 * @param action
	 */
	private static void runWithSpring(Runnable action) {
        ConfigurableApplicationContext context = null;
        try {
        	// 加载spring环境
            SpringApplication app = new SpringApplication(HtWebApiMain.class);
            app.setWebApplicationType(WebApplicationType.NONE);
            context = app.run();
            
            // 执行业务代码
            action.run();
        } finally {
            if (context != null) {
                //context.close();
            }
        }
	}
	
	/**
	 * 启动spring环境，并执行业务代码，然后返回一个值
	 * @param <T>
	 * @param action
	 * @return
	 */
	private static <T> T runWithSpring(Supplier<T> action) {
	    ConfigurableApplicationContext context = null;
	    try {
	        SpringApplication app = new SpringApplication(HtWebApiMain.class);
	        app.setWebApplicationType(WebApplicationType.NONE);
	        context = app.run();
	        
	        // 执行业务逻辑并返回结果
	        return action.get();
	    } finally {
	        if (context != null) {
	            //context.close();
	        }
	    }
	}
}
